package client

import (
	"context"
	"github.com/milkbobo/fishgoweb/language"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"miners-monitor/models/common"
)

const dbName = "client"

type ClientDbModel struct {
	common.BaseModel
	CommonFunc common.CommonFunc
}

func (this *ClientDbModel) FindOne(filter Client, opts *options.FindOneOptions) *mongo.SingleResult {
	filterBsonD := this.StructToBsonDAndAppendClientId(filter)
	return this.MDB.Collection(dbName).FindOne(context.TODO(), filterBsonD, opts)
}

func (this *ClientDbModel) Find(filter interface{}, opts *options.FindOptions) *mongo.Cursor {
	result, err := this.MDB.Collection(dbName).Find(context.TODO(), filter, opts)
	if err == mongo.ErrNoDocuments {
		return nil
	} else if err != nil {
		panic(err)
	}
	return result
}

func (this *ClientDbModel) Upsert(update Client) {
	filter := update
	filter.Password = ""
	filterBsonD, err := this.CommonFunc.StructToBsonD(filter)
	if err != nil {
		panic(err)
	}
	opts := options.Update().SetUpsert(true)
	updateBsonD, err := this.CommonFunc.StructToBsonD(update)
	if err != nil {
		panic(err)
	}
	updateSet := bson.D{{"$set", updateBsonD}}
	_, err = this.MDB.Collection(dbName).UpdateOne(context.Background(), filterBsonD, updateSet, opts)
	if err != nil {
		panic(err)
	}
}


func (this *ClientDbModel) Update(update Client) {
	if update.ClientId == "" {
		language.Throw(1,"ClientId不能为空")
	}

	filterBsonD := this.StructToBsonDAndAppendClientId(Client{ClientId: update.ClientId})

	update.ClientId = ""
	opts := options.Update()
	updateBsonD, err := this.CommonFunc.StructToBsonD(update)
	if err != nil {
		panic(err)
	}
	updateSet := bson.D{{"$set", updateBsonD}}
	_, err = this.MDB.Collection(dbName).UpdateOne(context.Background(), filterBsonD, updateSet, opts)
	if err != nil {
		panic(err)
	}
}

func (this *ClientDbModel) Del(clientId string) *mongo.DeleteResult {
	filterBsonD := this.StructToBsonDAndAppendClientId(Client{ClientId: clientId})
	result, err := this.MDB.Collection(dbName).DeleteOne(context.TODO(), filterBsonD, options.Delete())
	if err != nil {
		panic(err)
	}
	return result
}

func (this *ClientDbModel) CountDocuments(filter Client, opts *options.CountOptions) int64 {
	filterByte, err := this.CommonFunc.BsonMarshal(filter)
	if err != nil {
		panic(err)
	}
	result, err := this.MDB.Collection(dbName).CountDocuments(context.TODO(), filterByte, opts)
	if err == mongo.ErrNoDocuments {
		return 0
	} else if err != nil {
		panic(err)
	}
	return result
}

func (this *ClientDbModel) StructToBsonDAndAppendClientId(data Client) bson.D {
	oldFilter := data
	data.ClientId = ""
	filterBsonD, err := this.CommonFunc.StructToBsonD(data)
	if err != nil {
		panic(err)
	}
	if oldFilter.ClientId != "" {
		ojId, err := primitive.ObjectIDFromHex(oldFilter.ClientId)
		if err != nil {
			panic(err)
		}
		filterBsonD = append(filterBsonD, bson.E{"_id", ojId})
	}

	return filterBsonD
}
